import json
from django.http import JsonResponse
from django.views.generic import View
from ..utils.literUtils import handle_serializer_error
from ..serializers.globalTableListSerializer import GlobalTableListQuerySerializer, GlobalTableListConfigSerializer
from ..serializers.globalTableInfoSerializer import GlobalTableCreateSerializer, GlobalTableInfoSerializer
from django.db.models import Q
from django.core.paginator import Paginator
from utils.encryptionAndDecryptionUtil import get_useraccount_from_request
from datetime import datetime
import traceback
from control.models.User import User
from ..models import GlobalTables

class GlobalTableView(View):
    def get(self, request, global_table_type):
        res = {"code": 400, "message": "", "data": None}
        try:
            data = request.GET
            # print(global_table_type)
            query_list_serializer = GlobalTableListQuerySerializer(data=data)
            data_valid = query_list_serializer.is_valid()
            if not data_valid:
                res["code"] = 400
                res["message"] = "参数错误：" + \
                    handle_serializer_error(
                        errors=query_list_serializer.errors)
                return JsonResponse(res)
            data = query_list_serializer.validated_data
            
            target_class = getattr(GlobalTables, global_table_type)
            all_list = target_class.objects.all().order_by('-create_date')
            
            query = Q()
            if "name" in data and data["name"] != "":
                query &= Q(name__icontains=data["name"])
            if "zh_name" in data and data["zh_name"] != "":
                query &= Q(zh_name__icontains=data["zh_name"])
                
            order_list_combined = []
            prop_list = data.get('sort_prop', '').split(
                ',') if data.get('sort_prop') else []
            order_list = data.get('sort_order', '').split(
                ',') if data.get('sort_order') else []
            if len(prop_list) != len(order_list):
                res["code"] = 400
                res["message"] = "排序参数错误"
                return JsonResponse(res)
            for i in range(len(prop_list)):
                for prop, order in zip(prop_list, order_list):
                    if order.lower() == 'ascending':
                        order_list_combined.append(prop)
                    elif order.lower() == 'descending':
                        order_list_combined.append(f'-{prop}')
                        
            if len(query) != 0:
                all_list = all_list.filter(query)
            if len(order_list_combined) != 0:
                all_list = all_list.order_by(*order_list_combined)
            total_count = all_list.count()
            res_data = {}
            if "page_size" in data:
                page_size = data["page_size"]
                current_page = data["current_page"]
                paginator = Paginator(all_list, page_size)
                if current_page > paginator.num_pages:
                    current_page = paginator.num_pages
                page_obj = paginator.get_page(current_page)
                res_data["current_page"] = current_page
                res_data["page_size"] = page_size
                res_data["total_count"] = total_count
                liter_list_serializer = GlobalTableListConfigSerializer(
                    page_obj, many=True)
                res_data["objects"] = liter_list_serializer.data
                res["code"] = 200
                res["message"] = "查询成功"
                res["data"] = res_data
                return JsonResponse(res)
            res_data["total_count"] = total_count
            liter_list_serializer = GlobalTableListConfigSerializer(
                all_list, many=True)
            res_data["objects"] = liter_list_serializer.data
            res["code"] = 200
            res["message"] = "查询成功"
            res["data"] = res_data
            return JsonResponse(res)
        except Exception as e:
            traceback.print_exc()
            res["code"] = 500
            res["message"] = "服务器错误：" + str(e)
        return JsonResponse(res)
    
    def post(self, request, global_table_type):
        res = {"code": 400, "message": "", "data": None}
        try:
            user_name = get_useraccount_from_request(request=request)
            u = User.objects.filter(user_account=user_name)[0]
            # print(request.body)
            data = json.loads(request.body)
            
            add_serializer = GlobalTableCreateSerializer(data=data)
            data_valid = add_serializer.is_valid()
            if not data_valid:
                print(add_serializer.errors)
                serial_errors = handle_serializer_error(
                    errors=add_serializer.errors)
                res["code"] = 400
                res["message"] = "参数错误：\n" + serial_errors
                return JsonResponse(res)
            data = add_serializer.validated_data
            # print(data)
            data["creator"] = u
            data["last_editor"] = u
            
            target_class = getattr(GlobalTables, global_table_type)
            # print(data)
            target_class.objects.create(**data)
            
            # add_serializer.save()
            res["code"] = 200
            res["message"] = "新建成功"
            res["data"] = None
        except Exception as e:
            traceback.print_exc()
            res["code"] = 500
            res["message"] = "服务器错误：" + str(e)
        return JsonResponse(res)
    

class GlobalTableInfoView(View):
    def get(self, request, id):
        res = {"code": 400, "message": "", "data": None}
        try:
            data = request.GET
            global_table_type = data['type']
            target_class = getattr(GlobalTables, global_table_type)
            target = target_class.objects.get(uuid=id)
            target = GlobalTableInfoSerializer(target).data
            print(target_class)
            res["code"] = 200
            res["message"] = "查询成功"
            res["data"] = target
        except Exception as e:
            traceback.print_exc()
            res["code"] = 500
            res["message"] = "服务器错误：" + str(e)
        return JsonResponse(res)
    
    def delete(self, request, id):
        res = {"code": 400, "message": "", "data": None}
        try:
            user_name = get_useraccount_from_request(request=request)
            data = json.loads(request.body)
            global_table_type = data['type']
            target_class = getattr(GlobalTables, global_table_type)
            target = target_class.objects.get(uuid=id)
            if target is None:
                res["code"] = 400
                res["message"] = "该条目不存在"
                return JsonResponse(res)
            
            if global_table_type == "Language":
                if target.literature_set.count() > 0:
                    res["code"] = 400
                    res["message"] = "删除失败：该语言条目已被文献引用"
                    return JsonResponse(res)
                elif target.book_set.count() > 0:
                    res["code"] = 400
                    res["message"] = "删除失败：该语言条目已被书籍引用"
                    return JsonResponse(res)
            elif global_table_type == "KeywordType":
                if target.keyword_set.count() > 0:
                    res["code"] = 400
                    res["message"] = "删除失败：该关键词类别条目已被关键词引用"
                    return JsonResponse(res)
            elif global_table_type == "DepartmentType":
                if target.department_set.count() > 0:
                    res["code"] = 400
                    res["message"] = "删除失败：该部门类别条目已被部门引用"
                    return JsonResponse(res)
            elif global_table_type == "InstitutionType":
                if target.institution_set.count() > 0:
                    res["code"] = 400
                    res["message"] = "删除失败：该机构类别条目已被机构引用"
                    return JsonResponse(res)
            elif global_table_type == "LiteratureStatusType":
                if target.literature_set.count() > 0:
                    res["code"] = 400
                    res["message"] = "删除失败：该文献状态条目已被文献引用"
                    return JsonResponse(res)
            elif global_table_type == "LiteratureType":
                if target.literature_set.count() > 0:
                    res["code"] = 400
                    res["message"] = "删除失败：该文献类型条目已被文献引用"
                    return JsonResponse(res)
            elif global_table_type == "JournalPublicationCycleType":
                if target.journal_set.count() > 0:
                    res["code"] = 400
                    res["message"] = "删除失败：该期刊出版周期条目已被期刊引用"
                    return JsonResponse(res)
            elif global_table_type == "ConferenceMeetingCycleType":
                if target.conference_set.count() > 0:
                    res["code"] = 400
                    res["message"] = "删除失败：该会议出版周期条目已被会议引用"
                    return JsonResponse(res)
            
            target.delete()
            res["code"] = 200
            res["message"] = "删除成功"
            res["data"] = None
        except Exception as e:
            res["code"] = 500
            res["message"] = "服务器错误：" + str(e)
        return JsonResponse(res)
    
    def put(self, request, id):
        res = {"code": 400, "message": "", "data": None}
        try:
            user_name = get_useraccount_from_request(request=request)
            u = User.objects.filter(user_account=user_name)[0]
            data = json.loads(request.body)
            target_class = getattr(GlobalTables, data['class_type'])
            
            target = target_class.objects.get(uuid=id)
            modify_serializer = GlobalTableCreateSerializer(instance=target, data=data)
            data_valid = modify_serializer.is_valid()
            if not data_valid:
                res["code"] = 400
                res["message"] = "参数错误：" + \
                    handle_serializer_error(
                        errors=modify_serializer.errors)
                return JsonResponse(res)
            data = modify_serializer.validated_data
            data["last_editor"] = u
            target.__dict__.update(**data)
            target.save()
            res["code"] = 200
            res["message"] = "编辑成功"
            res["data"] = None
        except Exception as e:
            res["code"] = 500
            res["message"] = "服务器错误：" + str(e)
            print(e)
        return JsonResponse(res)